package cn.edu.zzuli.stack;

public class Calculator {

    public static void main(String[] args) {
        String expr = "3+2*6-2";
        //创建两个栈
        //数栈
        LinkStack<Integer> numStack = new LinkStack<>();
        //符号栈
        LinkStack<Character> operStack = new LinkStack<>();
        StringBuilder num = new StringBuilder();
        int res = 0;

        //开始扫描 expr 表达式
        for (int i = 0; i < expr.length(); i++) {
            char val = expr.charAt(i);
            //判断是符号还是数字
            if (isOperator(val)) {
                //判断栈是否为空，为空直接入栈
                if (operStack.isEmpety()) {
                    operStack.push(val);
                    continue;
                }

                //不为空继续判断，判断 当前符号优先级 是否小于等于 栈顶的符号
                if (priority(val) <= priority((char)operStack.top())) {
                        res = cal((int)numStack.pop(),(int)numStack.pop(),(char)operStack.pop());
                        //将计算结果放入 数栈
                        numStack.push(res);
                        //新的符号入栈
                        operStack.push(val);
                } else {
                   //如果大于直接入栈
                    operStack.push(val);
                }

            }else {
                //是数字的话入数栈, 因为 char的实质是 ASCII码，'1'对应的是 49
                //numStack.push(val - 48);
                //处理多位数时，不能判断时数字就直接入栈
                //需要手动向后多判断一位,看是否时符号位
                while (true) {
                    num.append(expr.charAt(i));

                    //如果最后一位 是数字的话，直接入栈
                    if (i + 1 == expr.length()){
                        numStack.push(Integer.parseInt(num.toString()));
                        num.delete(0,num.length());
                        break;
                    }

                    //如果下一位是 运算符，说明 多位数遍历完了。 比如 10-1
                    if (isOperator(expr.charAt(i + 1))) {
                        numStack.push(Integer.parseInt(num.toString()));
                        num.delete(0,num.length());
                        break;
                    }

                    //手动后移
                    i++;
                }
            }
        }

        //expr遍历完后，开始计算栈中剩余的数据
        //符号栈为空，就意味着已经计算到最后的结果
        while (!operStack.isEmpety()) {
            res = cal((int)numStack.pop(),(int)numStack.pop(),(char)operStack.pop());
            //将计算结果放入 数栈
            numStack.push(res);
        }

        //最后栈顶的元素就是 最后结果
        System.out.println(numStack.top());
    }

    public static int priority(int oper) {
        if (oper == '*' || oper == '/') {
            return 10;
        } else if (oper == '+' || oper == '-') {
            return 5;
        }

        return -1;
    }

    public static boolean isOperator(char val) {
        return  val == '+' ||
                val == '-' ||
                val == '*' ||
                val == '/';
    }

    public static int cal(int num1, int num2, int oper) {
        int res = 0;
        switch (oper) {
            case '+' :
                res = num2 + num1;
                break;
            case '-' :
                res = num2 - num1;
                break;
            case '*' :
                res = num2 * num1;
                break;
            case '/' :
                res = num2 / num1;
                break;
        }

        return res;
    }
}
